﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace SharpWeb
{
    /// <summary>
    /// 标签的属性
    /// </summary>
    public class TagAttribute
    {
        public TagAttribute(string key, string value)
        {
            _Name = key;
            _Value = value;
        }

        private string _Name;
        /// <summary>
        /// 属性名称
        /// </summary>
        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }
        private string _Value;
        /// <summary>
        /// 属性值
        /// </summary>
        public virtual string Value
        {
            get { return _Value; }
            set { _Value = value; }
        }

        public override string ToString()
        {
            return this.Name + @"=""" + this.Value + @"""";
        }
    }
    /// <summary>
    /// 组件的样式属性
    /// </summary>
    public class TagStyleAttribute : TagAttribute
    {
        public TagStyleAttribute(string key, string value)
            : base(key, null)//先不要设置基类的value
        {
            styles = new Dictionary<string, string>();
            this.Value = value;
        }
        private readonly Dictionary<string, string> styles;
        public override string Value
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                foreach (var item in this.styles)
                {
                    sb.Append(item.Key + ":" + item.Value + ";");
                }
                base.Value = sb.ToString();
                return base.Value;
            }
            set
            {
                base.Value = value;
                this.styles.Clear();
                string[] strs = value.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                foreach (var item in strs)
                {
                    string[] kv = item.Split(':');
                    this.styles.Add(kv[0].Trim(), kv[1].Trim());
                }
            }
        }

        public string this[string stylename]
        {
            get { return GetStyle(stylename); }
            set { this.SetStyle(stylename, value); }
        }
        public string GetStyle(string stylename)
        {
            if (this.styles.ContainsKey(stylename))
                return styles[stylename];
            else
                return "";
        }
        /// <summary>
        /// 设置样式
        /// </summary>
        /// <param name="stylename"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public void SetStyle(string stylename, string value)
        {
            if (this.styles.ContainsKey(stylename))
                styles[stylename] = value;
            else
                this.styles.Add(stylename, value);

        }
    }
    /// <summary>
    /// 组件的Class属性
    /// </summary>
    public class TagClassAttribute : TagAttribute
    {
        private readonly List<string> classes;
        public TagClassAttribute(string key, string value)
            : base(key, null)
        {
            classes = new List<string>();
            this.Value = value;
        }
        public override string Value
        {
            get
            {
                base.Value = string.Join(" ", classes.ToArray());
                return base.Value;
            }
            set
            {
                classes.Clear();
                foreach (var item in value.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
                    classes.Add(item);
            }
        }
        /// <summary>
        /// 添加类名
        /// </summary>
        /// <param name="class"></param>
        public void AddClass(string @class)
        {
            @class = @class.ToLower();
            if (!classes.Contains(@class))
            {
                classes.Add(@class);
            }
        }
        /// <summary>
        /// 移除类名
        /// </summary>
        /// <param name="class"></param>
        public void RemoveClass(string @class)
        {
            @class = @class.ToLower();
            if (classes.Contains(@class))
            {
                classes.Remove(@class);
            }
        }
    }
    /// <summary>
    /// 组件状态集合
    /// </summary>
    public class TagAttributeCollection : KeyedCollection<string, TagAttribute>
    {
        /// <summary>
        /// 初始化状态
        /// </summary>
        /// <param name="keys"></param>
        public void InitStates(IEnumerable<string> keys)
        {
            this.Clear();
            foreach (var item in keys)
            {
                this.Add(new TagAttribute(item, string.Empty));
            }
        }
        /// <summary>
        /// 通过属性名称访问或设置属性值，若设置为null值则移除此属性。
        /// </summary>
        /// <param name="attname"></param>
        /// <returns></returns>
        public new string this[string attname]
        {
            get
            {
                if (this.Contains(attname))
                    return base[attname].Value;
                return null;
            }
            set
            {
                bool exists = this.Contains(attname);
                if (value == null && exists)
                {//指定值为NULL，移除此属性
                    this.Remove(attname);
                }
                else if (exists)
                {
                    base[attname].Value = value;
                }
                else
                    this.Add(attname, value);
            }
        }
        /// <summary>
        /// 访问此属性会在属性集合中插入class项，慎用。
        /// </summary>
        public TagClassAttribute Class
        {
            get
            {
                if (!this.Contains("class")) 
                    this.Add("class", ""); 
                return (TagClassAttribute)base["class"];
            }
        }

        /// <summary>
        /// 访问此属性会在属性集合中插入style项，慎用。
        /// </summary>
        public TagStyleAttribute Style
        {
            get
            {
                if (!this.Contains("style")) 
                    this.Add("style", ""); 
                return (TagStyleAttribute)base["style"];
            }
        }

        protected override void InsertItem(int index, TagAttribute item)
        {
            if (item.Name.Equals("style", StringComparison.CurrentCultureIgnoreCase))
                this.Insert(index, new TagStyleAttribute(item.Name, item.Value));
            else if (item.Name.Equals("class", StringComparison.CurrentCultureIgnoreCase))
                this.Insert(index, new TagClassAttribute(item.Name, item.Value));
            else
                base.InsertItem(index, item);
        }

        protected override void SetItem(int index, TagAttribute item)
        {
            if (item.Name.Equals("style", StringComparison.CurrentCultureIgnoreCase))
                this.SetItem(index, new TagStyleAttribute(item.Name, item.Value));
            else if (item.Name.Equals("class", StringComparison.CurrentCultureIgnoreCase))
                this.SetItem(index, new TagClassAttribute(item.Name, item.Value));
            else
                base.SetItem(index, item);
        }
        private void Add(string attname, string value)
        {
            this.Add(new TagAttribute(attname, value));
        }

        /// <summary>
        /// 获取属性的字符串形式
        /// </summary>
        /// <param name="attname">属性名称</param>
        /// <returns>返回 属性="属性值" 的形式</returns>
        public virtual string GetAttributeString(string attname)
        {
            if (this.Contains(attname))
            {
                TagAttribute state = base[attname];
                return state.ToString();
            }
            return "";
        }

        protected override string GetKeyForItem(TagAttribute item)
        {
            return item.Name;
        }
    }
}
